package com.loonyhom.musicplayer.Control;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Environment;
import android.util.Log;

import com.loonyhom.musicplayer.Tools.FileUtilTool;
import com.loonyhom.musicplayer.Tools.MusicInfo;

public class MusicPlayControl implements OnCompletionListener {

	private static final String TAG = "MusicPlayControl";
	private static MusicPlayControl instance = null;
	private MusicState state;
	private PlayMode mode;
	private int index = 0;
	private Context context;
	private MusicPlayListener musicListener = null;

	public interface MusicPlayListener {
		void onCompletionMusic();
	}

	private ArrayList<HashMap<String, Object>> files = new ArrayList<HashMap<String, Object>>();
	private ArrayList<MusicInfo> playlist = new ArrayList<MusicInfo>();

	private MediaPlayer mPlayer = null;

	public enum MusicState {
		idle, playing, pause, stop, error
	}

	public enum PlayMode {
		listmode, randomode, onemode
	}

	public static MusicPlayControl getInstance() {
		if (null == instance) {
			instance = new MusicPlayControl();
		}
		return instance;
	}

	public void setMusicPlayListener(MusicPlayListener musicListener) {
		this.musicListener = musicListener;
	}

	public MusicPlayListener getMusicPlayListener() {
		return musicListener;
	}

	public void init(Context context) {
		Log.i(TAG, "initialize");
		this.context = context;
		scanMusicFile();
		if (null == mPlayer) {
			mPlayer = new MediaPlayer();
			mPlayer.setOnCompletionListener(this);
			Log.i(TAG, "scanMusicFile");
		}
		state = MusicState.idle;
		mode = PlayMode.listmode;
	}

	public ArrayList<MusicInfo> getMusicPlayList() {
		return playlist;
	}

	public int getPlaylistSize() {
		if (playlist != null) {
			return playlist.size();
		} else {
			return 0;
		}
	}

	private boolean isMountedSDCard() {
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			return true;
		} else {
			return false;
		}
	}

	public void startPlayMusic() {
		switch (state) {
		case idle:
		case stop:
			start();
			break;
		case playing:
			mPlayer.pause();
			state = MusicState.pause;
			break;
		case pause:
			mPlayer.start();
			state = MusicState.playing;
			break;
		default:
			Log.i(TAG, "play music is error");
			break;
		}
	}

	public void startPlayMusic(int index) {
		mPlayer.stop();
		this.index = index;
		start();
	}

	public boolean seekTo(int time) {
		if (playlist.size() <= 0) {
			return false;
		}
		mPlayer.seekTo(time);
		return true;
	}

	// 上一首
	public boolean playPreMusic() {
		if (mode == PlayMode.randomode) {
			index = randomIndexFromList();
			Log.i(TAG, "index = " + index);
		} else {
			if (playlist.size() <= 0) {
				return false;
			}
			if ((index - 1) >= 0) {
				index--;
			} else {
				index = playlist.size() - 1;
			}
		}

		switch (state) {
		case playing:
		case pause:
			start();
			break;
		case stop:
		default:
			break;
		}
		return true;
	}

	// 下一自首
	public boolean playNextMusic() {
		if (mode == PlayMode.randomode) {
			index = randomIndexFromList();
			Log.i(TAG, "index = " + index);
		} else {
			if (playlist.size() <= 0) {
				return false;
			}
			if (index + 1 < playlist.size()) {
				index++;
			} else {
				index = 0;
			}
		}

		switch (state) {
		case playing:
		case pause:
			start();
			break;
		case stop:
		default:
			break;
		}
		return true;
	}

	// 开始播放
	private boolean start() {

		if (playlist.size() > 0 && index < playlist.size()) {
			String SongPath = playlist.get(index).geturl();
			Log.i(TAG, "songpath = " + SongPath);
			mPlayer.reset();
			try {
				mPlayer.setDataSource(SongPath);
				mPlayer.prepare();
				mPlayer.start();
				state = MusicState.playing;
			} catch (IOException e) {
				e.printStackTrace();
				Log.i(TAG, e.getMessage());
			}
			return true;
		}
		return false;
	}

	private int randomIndexFromList() {
		int size = getPlaylistSize();
		Log.i(TAG, "size = " + size);
		int i = (int) (Math.random() * (size - 1));
		Log.i(TAG, "i = " + i);
		return i;
	}

	// public boolean stopMusicPlay() {
	// if (playlist.size() <= 0) {
	// return false;
	// }
	// mPlayer.stop();
	// state = MusicState.stop;
	// return true;
	// }

	public void releaseMediaPlayer() {
		if (mPlayer != null) {
			mPlayer.reset();
			mPlayer.release();
			mPlayer = null;
			state = MusicState.idle;
		}
	}

	public void onCompletion(MediaPlayer mp) {
		if (mode == PlayMode.onemode) {
			index = getCurrentIndex();
			start();
		} else if (mode == PlayMode.randomode) {
			index = randomIndexFromList();
			start();
		} else {
			playNextMusic();
		}
		musicListener.onCompletionMusic();
	}

	public boolean isMusicPlaying() {
		return state == MusicState.playing;
	}

	public boolean scanMusicFile() {

		if (!isMountedSDCard()) {
			return false;
		}
		if (playlist != null) {
			playlist.clear();
		}
		files = FileUtilTool.scanAllAudioFiles(context);
		for (int i = 0; i < files.size(); i++) {
			MusicInfo info = new MusicInfo();
			info.setSongid(files.get(i).get("id").toString());
			info.setTitle(files.get(i).get("title").toString());
			info.setAlbum(files.get(i).get("album").toString());
			info.setAlbumid(files.get(i).get("albumid").toString());
			info.setArtist(files.get(i).get("artist").toString());
			info.seturl(files.get(i).get("url").toString());
			info.setDuration(files.get(i).get("duration").toString());
			playlist.add(info);
		}
		return false;
	}

	public MusicState getPlayState() {
		return state;
	}

	public MusicInfo getCurrentMusicObject() {
		if (playlist == null || playlist.isEmpty()) {
			return null;
		}
		return playlist.get(index);
	}

	public int getCurrentIndex() {
		return index;
	}

	public PlayMode getMode() {
		return mode;
	}

	public void setMode(PlayMode mode) {
		this.mode = mode;
	}

	public String getLrcName() {
		if (playlist.isEmpty()) {
			return "";
		}
		String name = playlist.get(index).getTitle() + "--"
				+ playlist.get(index).getArtist() + ".lrc";
		Log.i(TAG, "index = " + index + ",name = " + name);

		return name;
	}
}
